﻿#region << 文 件 说 明 >>

/*----------------------------------------------------------------
// 文件名称：SetAppStart
// 创 建 者：杨程
// 创建时间：2021/11/8 15:40:34
// 文件版本：V1.0.0
// ===============================================================
// 功能描述：
//
//
//----------------------------------------------------------------*/

#endregion

namespace Vampirewal.Core;

/// <summary>
/// 设置应用程序开机启动/取消开机启动
/// <para>appName = Process.GetCurrentProcess().MainModule.ModuleName;</para>
/// <para>appPath = Process.GetCurrentProcess().MainModule.FileName;</para>
/// </summary>
public class SetAppStart
{
    /// <summary>
    /// 将本程序设为开启自启
    /// </summary>
    /// <param name="onOff">自启开关</param>
    /// <returns></returns>
    public static bool SetMeStart(bool onOff)
    {
        string appName = Process.GetCurrentProcess().MainModule.ModuleName;
        string appPath = Process.GetCurrentProcess().MainModule.FileName;

        return SetAutoStart(onOff, appName, appPath);
    }

    /// <summary>
    /// 将应用程序设为或不设为开机启动
    /// </summary>
    /// <param name="onOff">自启开关</param>
    /// <param name="appName">应用程序名</param>
    /// <param name="appPath">应用程序完全路径</param>
    public static bool SetAutoStart(bool onOff, string appName, string appPath)
    {
        bool isOk = true;
        //如果从没有设为开机启动设置到要设为开机启动
        if (!IsExistKey(appName) && onOff)
        {
            isOk = SelfRunning(onOff, appName, @appPath);
        }
        //如果从设为开机启动设置到不要设为开机启动
        else if (IsExistKey(appName) && !onOff)
        {
            isOk = SelfRunning(onOff, appName, @appPath);
        }
        return isOk;
    }

    /// <summary>
    /// 判断注册键值对是否存在，即是否处于开机启动状态
    /// </summary>
    /// <param name="appName">键值名</param>
    /// <returns></returns>
    private static bool IsExistKey(string appName)
    {
        try
        {
            bool _exist = false;
            RegistryKey local = Registry.LocalMachine;
            RegistryKey runs = local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
            if (runs == null)
            {
                RegistryKey key2 = local.CreateSubKey("SOFTWARE");
                RegistryKey key3 = key2.CreateSubKey("Microsoft");
                RegistryKey key4 = key3.CreateSubKey("Windows");
                RegistryKey key5 = key4.CreateSubKey("CurrentVersion");
                RegistryKey key6 = key5.CreateSubKey("Run");
                runs = key6;
            }
            string[] runsName = runs.GetValueNames();
            foreach (string strName in runsName)
            {
                if (strName.ToUpper() == appName.ToUpper())
                {
                    _exist = true;
                    return _exist;
                }
            }
            return _exist;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 写入或删除注册表键值对,即设为开机启动或开机不启动
    /// </summary>
    /// <param name="isStart">是否开机启动</param>
    /// <param name="exeName">应用程序名</param>
    /// <param name="path">应用程序路径带程序名</param>
    /// <returns></returns>
    private static bool SelfRunning(bool isStart, string exeName, string path)
    {
        try
        {
            RegistryKey local = Registry.LocalMachine;
            RegistryKey key = local.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);
            if (key == null)
            {
                local.CreateSubKey("SOFTWARE//Microsoft//Windows//CurrentVersion//Run");
            }
            //若开机自启动则添加键值对
            if (isStart)
            {
                key.SetValue(exeName, path);
                key.Close();
            }
            else//否则删除键值对
            {
                string[] keyNames = key.GetValueNames();
                foreach (string keyName in keyNames)
                {
                    if (keyName.ToUpper() == exeName.ToUpper())
                    {
                        key.DeleteValue(exeName);
                        key.Close();
                    }
                }
            }
        }
        catch (Exception ex)
        {
            string ss = ex.Message;
            return false;
            //throw;
        }

        return true;
    }
}